from certificate_manager.models import *
from certificate_manager.serializers import CertSerializer
from django.test import tag
from rest_framework import status
from rest_framework.renderers import JSONRenderer
from rest_framework.test import APITestCase, force_authenticate, APIClient
from rest_framework.authtoken.models import Token
import datetime

class CateTestCase(APITestCase):

        def setUp(self):
                dep1 = Department.objects.create(name='test1')
                dep1.save()
                Department.objects.create(name='test2').save()

                # 修改本节内容需要管理员权限
                User.objects.create_superuser(uid='1', password='123', name='yves', department=dep1)

                class MyAPIClient(APIClient):
                    def login(self, *args, **kwargs):
                        token = Token.objects.get(user__uid=kwargs['uid'])
                        self.credentials(HTTP_AUTHORIZATION='Token ' + token.key)
                        return super().login(*args, **kwargs)

                    def logout(self):
                        self.credentials()
                        return super().logout()

                self.client = MyAPIClient()
        

        def test_add_cate(self):
                url = '/cates/'
                data = {
                        'name': 'Test Cate',
                        'nested_cate': None,
                        'collect_part': Cate.NAME,
                        'restricts': [
                                {
                                        'department': 1,
                                        'restrict_type': DepartRestrict.JOINER,
                                        'people_limit': 2,
                                        'priority': 0
                                },
                                {
                                        'department': 2,
                                        'restrict_type': DepartRestrict.ADVISOR,
                                        'people_limit': 2,
                                        'priority': 1
                                },
                        ]
                }
                self.client.login(uid='1', password='123')
                response = self.client.post(url, data, format='json')
                print(response.data)
                self.assertEqual(response.status_code, status.HTTP_201_CREATED)

                self.assertEqual(Cate.objects.count(), 1)
                cate = Cate.objects.get(pk=response.data['pk']) 
                self.assertEqual(cate.name, data['name'])

                # 还有一些看似”无关“的属性需要添加
                self.assertEqual(cate.collect_part, data['collect_part'])

                # 检查一下限制添加上没有
                self.assertEqual(cate.departrestrict_set.count(), 2)


                # 我们再添加一个通过等级创建的
                data = {
                        'name': 'Test Cate 2',
                        'nested_cate': None,
                        'collect_part': Cate.LEVEL,
                        'departrestrict_set': [
                                {
                                        'department': 1,
                                        'people_limit': 2,
                                        'priority': 0
                                },
                                {
                                        'department': 2,
                                        'people_limit': 2,
                                        'priority': 1
                                },
                        ],
                        'levels': [
                                {
                                        'name': '国家级',
                                        'nested_level': [
                                                {
                                                        'name': '一等奖'
                                                },
                                                {
                                                        'name': '二等奖'
                                                },
                                                {
                                                        'name': '三等奖'
                                                }
                                        ]
                                },
                                {
                                        'name': '省级',
                                        'nested_level': [
                                                {
                                                        'name': '一等奖'
                                                },
                                                {
                                                        'name': '二等奖'
                                                },
                                                {
                                                        'name': '三等奖'
                                                }
                                        ]
                                }
                        ]
                }
                response = self.client.post(url, data, format='json')
                print(response.data)
                self.assertEqual(response.status_code, status.HTTP_201_CREATED)

                # 下面要验证对应的level是否都创建出来了
                '''
                预想的level结构
                -> 国家级
                        -> 一等奖
                        -> 二等奖
                        -> 三等奖
                -> 省级
                        -> 一等奖
                        -> 二等奖
                        -> 三等奖
                '''
                cate = Cate.objects.get(name='Test Cate 2')
                self.assertEqual(cate.level_set.count(), 2)
                for level in cate.level_set.all():
                        self.assertEqual(level.level_set.count(), 3)
                

        @classmethod
        def add_cates(clazz, cate_list=[]):
                # [ ('Cate Name', id), ... ]
                for cate_name, nested_cate_id in cate_list:
                        if nested_cate_id:
                                nested_cate = Cate.objects.get(pk=nested_cate_id)
                        else:
                                nested_cate = None
                        cate = Cate.objects.create(name=cate_name, nested_cate=nested_cate)
                        cate.save()


        def test_util_add_cate(self):
                self.add_cates([('超级赛事', None), ('互联网+', 1), ('创新创业项目', 1)])
                
                self.assertEqual(Cate.objects.filter(layer=0).count(), 1)
                self.assertEqual(Cate.objects.filter(layer=1).count(), 2)


        def test_get_cate_list(self):
                cate_list = [('超级赛事', None), ('互联网+', 1), ('创新创业项目', 1)]
                self.add_cates(cate_list)

                url = '/cates/'
                data = {}
                response = self.client.get(url, data, format='json')
                self.assertEqual(response.status_code, status.HTTP_200_OK)
                
                self.assertEqual(len(response.data), len(cate_list))
                self.assertEqual(Cate.objects.filter(layer=0).count(), 1)
                self.assertEqual(Cate.objects.filter(layer=1).count(), 2)


        def test_update_cate(self):
                # 在admin口没有问题，但是restful有问题
                # cate_list = [('超级赛事', None), ('我是谁', None)]
                # self.add_cates(cate_list)
                # 
                # url = '/cates/1/'
                # data = {
                #       'name': '不是超级赛事',
                #       'nested_cate': 2,
                # }
                # self.client.login(uid='1', password='123')
                # response = self.client.patch(url, data, format='json')
                # self.assertEqual(response.status_code, status.HTTP_200_OK)
                # self.assertEqual(Cate.objects.filter(layer=1).count(), 1)
                # self.assertEqual(Cate.objects.filter(layer=0).count(), 1)
                pass


'''
Cert显示字段控制
'''
class CertSegTests(APITestCase):
        def setUp(self):
                # 我们要创建几个不同类型的竞赛，看其返回的结果
                c_n_g = Cate.objects.create(name='cate for name group', collect_part=Cate.NAME)
                c_n_g.save()
                c_n_s = Cate.objects.create(name='cate for name single', collect_part=Cate.NAME)
                c_n_s.save()

                c_l_g = Cate.objects.create(name='cate for level group', collect_part=Cate.LEVEL)
                c_l_g.save()
                c_l_s = Cate.objects.create(name='cate for level single', collect_part=Cate.LEVEL)
                c_l_s.save()
                
                c_s_g = Cate.objects.create(name='cate for score group', collect_part=Cate.LEVEL)
                c_s_g.save()
                c_s_s = Cate.objects.create(name='cate for score single', collect_part=Cate.LEVEL)
                c_s_s.save()

                # 下面还需要创建对应的collect cate
                CollectCate.objects.create(cate=c_n_g).save()
                CollectCate.objects.create(cate=c_n_s).save()

                CollectCate.objects.create(cate=c_l_g).save()
                CollectCate.objects.create(cate=c_l_s).save()

                CollectCate.objects.create(cate=c_s_g).save()
                CollectCate.objects.create(cate=c_s_s).save()

                # 还需要创建个用户
                department = Department.objects.create(name='test dep')
                department.save()
                User.objects.create_user(uid='1', name='test', password='123', department=department)

                class MyAPIClient(APIClient):
                    def login(self, *args, **kwargs):
                        token = Token.objects.get(user__uid=kwargs['uid'])
                        self.credentials(HTTP_AUTHORIZATION='Token ' + token.key)
                        return super().login(*args, **kwargs)

                    def logout(self):
                        self.credentials()
                        return super().logout()

                self.client = MyAPIClient()

        def test_cert_seg_show(self):
                # 测试证书的字段显示问题-之后再做吧
                pass

        def test_cert_seg_valid_unauth(self):
                # 未登陆创建证书，应当报错
                url = '/certs/'
                data = {
                        'cate': 1,
                        'name': '100', # 应当为name
                        'score': '100', # 应当为name
                        'achieved_date': '2020-01-01',
                        'join_list': [ # 第一个人必须是申请人 需要参数检查
                        ],
                        'pics': []
                }
                response = self.client.post(url, data, format='json')
                self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

        def test_cert_seg_valid_auth(self):
                # 创建非法证书，检查字段后报错
                url = '/certs/'
                data = {
                        'cate': 1,
                        'name': '100', # 应当为name
                        'score': '100', # 应当为name
                        'achieved_date': '2020-01-01',
                        'join_list': [ # 第一个人必须是申请人 需要参数检查
                            {
                                'restrict': 1,
                                'play_role_imp': 100,
                                'uid': 1
                            }
                        ],
                        'pics': []
                }
                self.client.login(uid='1', password='123')
                response = self.client.post(url, data, format='json')
                print(response.data)
                self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        @tag('c')
        def test_just_get_list(self):
                url = '/cates/?format=json'
                response = self.client.get(url, format='json')
                print(response.data)
                self.assertEqual(response.status_code, status.HTTP_200_OK)


